

import parseAPNG, { APNG } from "apng-js";
import axios from "axios";
import { isEmpty } from "lodash";
import { MirroredRepeatWrapping, Texture, TextureLoader } from "three";
import threeUtils from "./threeUtils";



/**
 * apng 纹理管理对象
 */
class apngTextureManage {

    constructor() {

        // 初始化定时更新时间戳
        if (apngTextureManage.isInit) {
            apngTextureManage.isInit = false;
            threeUtils.addEventListener("requestAnimationFrame5000", (e: any) => {
                apngTextureManage.TimeTemp = e.timeTemp;
            });
        }

    }

    static TextureLoader = new TextureLoader();

    static isInit = true;

    // 获取时间戳
    static TimeTemp = performance.now();

    // 每个动态纹理的播放总时长
    playTimes = new Map();

    // 保存所有的动态纹理
    anpgTextList: { [key: string]: Texture[] } = {};

    // 获取动态纹理 需要每帧都获取一下
    getTexture(path: string) {
        // 如果 没有这个纹理就返回空同时开始加载这个纹理
        if (!this.anpgTextList[path]) {
            this.anpgTextList[path] = [];

            this.loadApng(path);

            return null;

        } else if (isEmpty(this.anpgTextList[path])) {

            return null;

        } else {

            const playTime = this.playTimes.get(path);
            let currentTime = apngTextureManage.TimeTemp % playTime;

            let i = 0;
            while (this.anpgTextList[path][i] && currentTime > Number(this.anpgTextList[path][i].name)) {
                currentTime -= Number(this.anpgTextList[path][i].name);
                i++;
            }

            this.anpgTextList[path][i].needsUpdate = true;

            return this.anpgTextList[path][i];
        }
    }

    // 加载apng图片
    async loadApng(url: string) {

        const res = await axios.get(url, { method: "post", responseType: "blob" });

        const blob = new Blob([res.data]);

        const reader = new FileReader();

        await new Promise<void>((resolve) => {
            reader.onload = () => resolve();
            reader.readAsArrayBuffer(blob);
        });

        const apng = (parseAPNG(reader.result as ArrayBuffer) as APNG);

        // 存储播放时长
        this.playTimes.set(url, apng.playTime);

        // for (let i = 0; i < apng.frames.length; i++) {
        //     const frame = apng.frames[i];
        //     frame.createImage();
        //     await new Promise(resolve => frame.imageElement!.onload = resolve);
        // }

        for (let i = 0; i < apng.frames.length; i++) {
            const frame = apng.frames[i];

            var blobUrl = URL.createObjectURL(frame.imageData!);

            const texture = apngTextureManage.TextureLoader.load(blobUrl);

            texture.anisotropy = 16;

            texture.wrapS = texture.wrapT = MirroredRepeatWrapping;

            // export const RepeatWrapping: Wrapping;
            // export const ClampToEdgeWrapping: Wrapping;
            // export const MirroredRepeatWrapping: Wrapping;

            // magFilter: TextureFilter;
            // minFilter: TextureFilter;


            texture.name = String(frame.delay);
            texture.center.set(0.5, 0.5);
            texture.repeat.set(apng.width / frame.width, apng.height / frame.height);
            // texture.needsUpdate = true;
            this.anpgTextList[url].push(texture);
        }

    }


}

const ApngTextureManage = new apngTextureManage();

export default ApngTextureManage;